package com.spukmk3me.util.gamestate;

import java.util.Hashtable;

public final class SectionManager
{
    public SectionManager( IGameState firstState,
        int firstStateID, int finishStateID )
    {
        m_stateTable    = new Hashtable<Integer, IGameState>();
        addState( firstState, firstStateID );
        m_currentStateID    = -1;
        m_firstStateID      = firstStateID;
        m_finishStateID     = finishStateID;
        m_firstTime         = true;
    }
    
    public void addState( IGameState state, int id )
    {
        if ( state == null )
            throw new IllegalArgumentException( "Null state" );
        
        if ( m_stateTable.containsKey( new Integer( id ) ) )
            throw new IllegalArgumentException( id + "already exists" );
        
        m_stateTable.put( new Integer( id ), state );
    }
    
    public void pause()
    {
        if ( m_currentState != null )
            m_currentState.pause();
    }
    
    public void resume()
    {
        if ( m_currentState != null )
            m_currentState.resume();
    }
    
    /**
     * 
     * @param timestep In milliseconds
     * @return true if state == finish state
     */
    public boolean execute( int timestep )
    {
        if ( m_firstTime )
            initFirstState();
        
        if ( m_currentState != null )
        {
            int nextStateID = m_currentState.execute( timestep );
            
            if ( (nextStateID != -1) && (nextStateID != m_currentStateID) )
            {
                if ( nextStateID == m_finishStateID )
                    return true;
                else
                {
                    IGameState newState = m_stateTable.get(
                        new Integer( nextStateID ) );
                    
                    if ( newState == null )
                        throw new IllegalArgumentException( "Next state doesn't exists." );
    
                    changeState( newState );
                }
                
                m_currentStateID = nextStateID;
            }
        }
        
        return false;
    }
    
    public void cleanup()
    {
        m_currentState.halt();
    }
    
    private void initFirstState()
    {
        IGameState firstState = m_stateTable.get( new Integer( m_firstStateID ) );
        
        if ( firstState == null )
            throw new IllegalArgumentException( "First state does not exist." );
        
        changeState( firstState );
        m_firstTime = false;
    }

    private void changeState( IGameState newState )
    {
        if ( m_currentState != null )
            m_currentState.rest();
        
        m_currentState = newState;
        m_currentState.wakeup();
    }

    private Hashtable<Integer, IGameState>  m_stateTable;
    private IGameState                      m_currentState;
    private int         m_currentStateID;
    private final int   m_firstStateID;
    private final int   m_finishStateID;
    private boolean     m_firstTime;
}
